#include "navigation.h"
#include "ui_navigation.h"

Navigation::Navigation(QWidget *parent) :
    QWidget(parent) , ui(new Ui::Navigation)
{
    ui->setupUi(this);
    //注册事件过滤
    installEventFilter(this);
    ui->mapWidget_7->installEventFilter(this);
    //初始化
    init();
}

void Navigation::init()
{
    //网络管理对象
    m_ipManager = new QNetworkAccessManager(this);
    //请求响应事件
    connect(m_ipManager, SIGNAL(finished(QNetworkReply *)), this, SLOT(onGetIp(QNetworkReply *)));
    //网络管理对象
    m_locManager = new QNetworkAccessManager(this);
    //请求响应事件
    connect(m_locManager,
            SIGNAL(finished(QNetworkReply *)),
            this,
            SLOT(onGetCurrentLoc(QNetworkReply *)));
    m_searchManager = new QNetworkAccessManager(this);
    connect(m_searchManager,
            SIGNAL(finished(QNetworkReply *)),
            this,
            SLOT(onSearchLoc(QNetworkReply *)));
    //网络管理对象
    m_mapManager = new QNetworkAccessManager(this);

    //读入路网数据
    readXMLFiles();
    //定位北理工
    m_lng = 116.178543;
    m_lat = 39.738114;
    m_zoom = 15;
    sendMapRequest();
}

//获取当前主机ip   发送请求
void Navigation::getIp()
{
    //此处无法获取外网ip
    //     QHostInfo info = QHostInfo::fromName(QHostInfo::localHostName());
    //     QString ip;
    //     foreach(QHostAddress address, QNetworkInterface::allAddresses()) {
    //           if (address.protocol() == QAbstractSocket::IPv4Protocol) {
    //                  qDebug() << "Current IP:" << address.toString();
    //                ip= address.toString();
    //            }
    //     }

    //请求http://httpbin.org/ip 获取外网ip

    //声明url 请求地址
    QUrl url("http://httpbin.org/ip");
    //声明请求对象
    QNetworkRequest request(url);
    //通过网络管理对象 发送get请求
    m_ipManager->get(request);
}

//处理服务器响应内容
void Navigation::onGetIp(QNetworkReply *reply)
{
    //reply->readAll()  服务响响应的正文内容
    //qDebug() << "Current IP:" << reply->readAll();
    QJsonDocument jsonDoc = QJsonDocument::fromJson(reply->readAll());
    QJsonObject jsonObj = jsonDoc.object();
    currentIp = jsonObj.value("origin").toString();
    qDebug() << "Current IP:" << currentIp << Qt::endl;

    //调用获取当前经纬度的函数
    getCurrentLoc();
}

//根据ip获取经纬度  发送请求
void Navigation::getCurrentLoc()
{
    //url
    QString host = "http://api.map.baidu.com/location/ip";
    QString query_str = QString("ip=%1&coor=bd09ll&ak=%2").arg(currentIp).arg(ak);
    //请求地址
    QUrl url(host + "?" + query_str);
    //请求对象
    //声明请求对象
    QNetworkRequest request(url);
    //发送请求
    m_locManager->get(request);
}

//根据ip获取经纬度  处理服务器响应内容
void Navigation::onGetCurrentLoc(QNetworkReply *reply)
{
    //    qDebug() << reply->readAll() <<endl;
    QJsonDocument jsonDoc = QJsonDocument::fromJson(reply->readAll());
    QJsonObject jsonObj = jsonDoc.object();
    QJsonObject jsonContent = jsonObj.value("content").toObject();
    QJsonObject jsonPonit = jsonContent.value("point").toObject();
    m_lng = jsonPonit.value("x").toString().toDouble();
    m_lat = jsonPonit.value("y").toString().toDouble();
    m_city = jsonContent.value("address_detail").toObject().value("city").toString();
    qDebug() << jsonPonit.value("x").toString() << Qt::endl;
    qDebug() << jsonPonit.value("y").toString() << Qt::endl;
    sendMapRequest();
}

void Navigation::readXMLFiles()
{
    // 打开文件
    QFile file("C://Users/cuichenhao/Desktop/zyc改/2024-on-board-system/OnBoardSystem/dataset/bit_map_data.osm");//(":/dataset/bit_map_data.osm");
    if (!file.open(QFileDevice::ReadOnly)) {
        QMessageBox::information(NULL, "提示", "文件打开失败！");
        return;
    }
    QDomDocument doc;
    if (!doc.setContent(&file)) {
        QMessageBox::information(NULL, "提示", "操作的文件不是XML文件！");
        file.close();
        return;
    }
    // 获得根节点
    QDomElement root = doc.documentElement();
    qDebug() << "根节点：" << root.nodeName();
    //获取经纬度范围
    QDomElement bounds = root.elementsByTagName("bounds").at(0).toElement();
    min_lon = bounds.attribute("minlon").toDouble();
    max_lon = bounds.attribute("maxlon").toDouble();
    min_lat = bounds.attribute("minlat").toDouble();
    max_lat = bounds.attribute("maxlat").toDouble();
    // 获取所有way节点node节点
    QDomNodeList way_list = root.elementsByTagName("way");
    QDomNodeList node_list = root.elementsByTagName("node");
    //存储node节点
    for (int i = 0; i < node_list.count(); i++) {
        QDomElement nodes = node_list.at(i).toElement();
        coordinatesStr Strnode = {i, nodes.attribute("lon"), nodes.attribute("lat")};
        nodeStrmap.insert(nodes.attribute("id"), Strnode);
        nodeIndexMap.insert(i, Strnode);
    }
    /* 获取属性中的值 */
    for (int i = 0; i < way_list.count(); i++) {
        // 获取链表中的值
        QDomElement way = way_list.at(i).toElement();
        // 找到需要读取的节点
        if (way.attribute("visible") == "true") {
            // 通过attribute方法返回属性中的值
            //qDebug() << "子节点：" << way.nodeName();
            //qDebug() << "id属性：" << way.attribute("id");

            QDomNodeList ndList = way.elementsByTagName("nd");
            // 只保留bit内部路网数据
            QDomNodeList tagList = way.elementsByTagName("tag");
            //if(tagList.at(1).toElement().attribute("v") != "北湖"&&tagList.at(1).toElement().attribute("v") != "北湖") continue;

            QList<QString> cur_node_list;
            for (int j = 0; j < ndList.count(); j++) {
                QDomElement childelement = ndList.at(j).toElement();
                if (childelement.nodeName() == "nd") {
                    //qDebug() << "ref属性：" << childelement.attribute("ref");
                    cur_node_list.append(childelement.attribute("ref"));
                }
            }
            // 存储当前路的节点数据
            road_data cur_way = {way.attribute("id"), cur_node_list};
            roadlist.append(cur_way);
        }
    }
    file.close();
}

// 发送请求  获取地图图片
void Navigation::sendMapRequest()
{
    //断调前一次请求
    if (m_mapReply != NULL) {
        m_mapReply->disconnect();
        //断掉事件连接
        disconnect(m_mapReply, &QIODevice::readyRead, this, &Navigation::onSendMapRequest);
    }
    //开始新的请求
    QString host = "http://api.map.baidu.com/staticimage/v2";
    //请求参数
    //116.178543,39.738114

    QString query_str = QString("ak=%1&width=512&height=256&center=%2,%3&zoom=%4&scale=2")
                            .arg(ak)
                            .arg(m_lng)
                            .arg(m_lat)
                            .arg(m_zoom);
    QUrl url(host + "?" + query_str);

    qDebug() << host + "?" + query_str << Qt::endl;
    QNetworkRequest request(url);
    //此处与前面的请求不同，等待服务器响应，
    m_mapReply = m_mapManager->get(request);
    //连接事件，处理服务器返回的 文件流
    connect(m_mapReply, &QIODevice::readyRead, this, &Navigation::onSendMapRequest);
}

//处理服务器返回地图图片
void Navigation::onSendMapRequest()
{
    //删除原有的地图图片 使用系统命令删除
    system("del map.png");
    //文件对象
    mapFile.setFileName(m_mapFileName);
    //读取文件流，保存文件到本地,
    //open 没有则新建文件，打开
    mapFile.open(QIODevice::WriteOnly | QIODevice::Truncate);
    m_timer.start(2);
    connect(&m_timer, &QTimer::timeout, [=]() {
        m_timer.stop();
        mapFile.write(m_mapReply->readAll());
        mapFile.close();

        QPixmap pixmap;
        if (pixmap.load(m_mapFileName)) {
            ui->mapWidget_7->setStyleSheet("QWidget{border-image:url(./map.png);}");
        }
    });
}

Navigation::~Navigation()
{
    delete ui;
}

//搜索地址  发送请求
void Navigation::on_searchBtn_7_clicked(bool checked)
{
    //1、取文本框的值
    qDebug() << ui->edit_search_7->text() << Qt::endl;
    //2、url
    QString host = "http://api.map.baidu.com/place/v2/search";
    /*
    QString query_str=QString("query=%1&location=%2,%3&output=json&ak=%4&radius=20000")
                            .arg(ui->edit_search->text()).arg(m_lat).arg(m_lng).arg(ak);
    */
    //输入不为空
    if (ui->edit_search_7->text() == "")
        return;
    QString query_str = QString("query=%1&output=json&ak=%4").arg(ui->edit_search_7->text()).arg(ak);

    QList<QString> list;
    list.append("湖北");
    list.append("湖南");
    list.append("北京");
    if (list.contains(ui->edit_search_7->text())) {
        query_str.append("&region=%1").arg(ui->edit_search_7->text());
    } else {
        query_str.append("&region=%1").arg(m_city);
    }
    QUrl url(host + "?" + query_str);
    qDebug() << host + "?" + query_str << Qt::endl;

    //3、request
    QNetworkRequest request(url);
    //4、发送请求
    m_searchManager->get(request);
}

//搜索地址  处理响应内容
void Navigation::onSearchLoc(QNetworkReply *reply)
{
    //    qDebug()<<reply->readAll()<<endl;
    QJsonDocument jsonDoc = QJsonDocument::fromJson(reply->readAll());
    reply->deleteLater();
    QJsonObject jsonObj = jsonDoc.object();
    QJsonArray addrArray = jsonObj.value("results").toArray();
    qDebug() << addrArray;
    QJsonObject addrJson = addrArray.at(0).toObject();
    QJsonObject xyJson = addrJson.value("location").toObject();
    m_lng = xyJson.value("lng").toDouble();
    m_lat = xyJson.value("lat").toDouble();
    m_city = addrJson.value("city").toString();

    qDebug() << m_lng << "," << m_lat << Qt::endl;
    m_zoom = 17;
    //调取地图图片的函数
    sendMapRequest();
}

//放大按钮，点击后改变m_zoom [3-18]
void Navigation::on_enlargeBtn_7_clicked()
{
    //判断m_zoom是否小于18，
    if (m_zoom < 19) {
        m_zoom += 1;
        //调用函数重新获取地图图片
        sendMapRequest();
    }
    on_clearBtn_7_clicked(true);
}
//缩小按钮，点击后改变m_zoom [3-18]
void Navigation::on_reduceBtn_7_clicked()
{
    if (m_zoom > 3) {
        m_zoom -= 1;
        sendMapRequest();
    }
    on_clearBtn_7_clicked(true);
}

//过滤事件
bool Navigation::eventFilter(QObject *watched, QEvent *event)
{
    //    qDebug()<<event->type()<<endl;
    if (isSelecting == false) {
        if (event->type() == QEvent::MouseButtonPress) {
            qDebug() << event->type() << cursor().pos().x() << ":" << cursor().pos().y()
                     << Qt::endl;
            isPress = true;
            startPoint.setX(cursor().pos().x());
            startPoint.setY(cursor().pos().y());
        }
        if (event->type() == QEvent::MouseButtonRelease) {
            qDebug() << event->type() << cursor().pos().x() << ":" << cursor().pos().y()
                     << Qt::endl;
            isRelease = true;
            endPoint.setX(cursor().pos().x());
            endPoint.setY(cursor().pos().y());
        }
        if (isPress && isRelease) {
            isPress = false;
            isRelease = false;
            //计算距离差
            mx = startPoint.x() - endPoint.x();
            my = startPoint.y() - endPoint.y();

            if (qAbs(mx) > 5 || qAbs(my) > 5) {
                m_lng += mx * 0.000002 * (19 - m_zoom) * (19 - m_zoom);
                m_lat -= my * 0.000002 * (19 - m_zoom) * (19 - m_zoom);
                sendMapRequest();
            }
        }
    } else if (isNavigating == false) {
        if (event->type() == QEvent::MouseButtonDblClick) {
            qDebug() << event->type() << cursor().pos().x() << ":" << cursor().pos().y()
                     << Qt::endl;
            //定位到mapWidget里
            int x = this->mapFromGlobal(QCursor().pos()).x();
            int y = this->mapFromGlobal(QCursor().pos()).y();
            qDebug() << x << ":" << y;
            double p_lon = getReal_lon(x - 9);
            double p_lat = getReal_lat(y - 160);
            //qDebug()<< cursor().pos().x()<<":"<<cursor().pos().y();
            if (isSelectingStartPoint == true) {
                startpoint_lon = p_lon;
                startpoint_lat = p_lat;
            } else {
                endpoint_lon = p_lon;
                endpoint_lat = p_lat;
            }
            m_note = QString::number(p_lon, 'f', 7) + "," + QString::number(p_lat, 'f', 7);
            qDebug() << m_note << Qt::endl;
            sendMapRequest();
        }
    } else if (isNavigating == true) {
        if (event->type() == QEvent::MouseButtonDblClick) {
            qDebug() << "正在改变目的地...";
            //定位到mapWidget里
            int x = this->mapFromGlobal(QCursor().pos()).x();
            int y = this->mapFromGlobal(QCursor().pos()).y();
            qDebug() << x << ":" << y;
            double p_lon = getReal_lon(x - 9);
            double p_lat = getReal_lat(y - 160);
            endpoint_lon = p_lon;
            endpoint_lat = p_lat;
            m_note = QString::number(p_lon, 'f', 7) + "," + QString::number(p_lat, 'f', 7);
            qDebug() << m_note << Qt::endl;
            sendMapRequest();
        }
    }
    if (watched == ui->mapWidget_7 && event->type() == QEvent::Paint && isSearching == false) {
        paintRoads();
    }
    return QWidget::eventFilter(watched, event);
}

//由经纬度转在图片中的绝对位置
double Navigation::getPic_definite_lon(double lon)
{
    double tm_lon;
    switch (m_zoom) {
    case 14:
        tm_lon = 75 * 1.7;
        break;
    case 15:
        tm_lon = 150 * 1.7;
        break;
    case 16:
        tm_lon = 300 * 1.7;
        break;
    case 17:
        tm_lon = 600 * 1.7;
        break;
    default:
        tm_lon = 600 * 1.7;
        break;
    }
    return (lon - min_lon) / (max_lon - min_lon) * tm_lon;
}
double Navigation::getPic_definite_lat(double lat)
{
    double tm_lat;
    switch (m_zoom) {
    case 14:
        tm_lat = 150 * 1.5;
        break;
    case 15:
        tm_lat = 300 * 1.5;
        break;
    case 16:
        tm_lat = 600 * 1.5;
        break;
    case 17:
        tm_lat = 1200 * 1.5;
        break;
    default:
        tm_lat = 1200 * 1.5;
        break;
    }
    return (max_lat - lat) / (max_lat - min_lat) * tm_lat;
}
//相对位置
double Navigation::getPiclon(double lon)
{
    double mv_lon;
    switch (m_zoom) {
    case 14:
        mv_lon = -getPic_definite_lon(m_lng) + 520;
        break;
    case 15:
        mv_lon = -getPic_definite_lon(m_lng) + 650;
        break;
    case 16:
        mv_lon = -getPic_definite_lon(m_lng) + 920;
        break;
    case 17:
        mv_lon = -getPic_definite_lon(m_lng) + 1450;
        break;
    default:
        mv_lon = -getPic_definite_lon(m_lng) + 1450;
        break;
    }
    return getPic_definite_lon(lon) + mv_lon;
}
double Navigation::getPiclat(double lat)
{
    double mv_lat = 0.0;
    switch (m_zoom) {
    case 14:
        mv_lat = -getPic_definite_lat(m_lat) + 95;
        break;
    case 15:
        mv_lat = -getPic_definite_lat(m_lat) - 15;
        break;
    case 16:
        mv_lat = -getPic_definite_lat(m_lat) - 220;
        break;
    case 17:
        mv_lat = -getPic_definite_lat(m_lat) - 630;
        break;
    default:
        mv_lat = -getPic_definite_lat(m_lat) - 630;
        break;
    }
    return getPic_definite_lat(lat) + mv_lat;
}
//转实际距离
double Navigation::getReal_lon(double lon)
{
    double real_lon;
    switch (m_zoom) {
    case 14:
        real_lon = (lon - 520 + getPic_definite_lon(m_lng)) / (75 * 1.7);
        break;
    case 15:
        real_lon = (lon - 650 + getPic_definite_lon(m_lng)) / (150 * 1.7);
        break;
    case 16:
        real_lon = (lon - 920 + getPic_definite_lon(m_lng)) / (300 * 1.7);
        break;
    case 17:
        real_lon = (lon - 1450 + getPic_definite_lon(m_lng)) / (600 * 1.7);
        break;
    default:
        real_lon = (lon - 1450 + getPic_definite_lon(m_lng)) / (600 * 1.7);
        break;
    }
    return real_lon * (max_lon - min_lon) + min_lon;
}
double Navigation::getReal_lat(double lat)
{
    double real_lat;
    switch (m_zoom) {
    case 14:
        real_lat = (lat - 95 + getPic_definite_lat(m_lat)) / (150 * 1.5);
        break;
    case 15:
        real_lat = (lat + 15 + getPic_definite_lat(m_lat)) / (300 * 1.5);
        break;
    case 16:
        real_lat = (lat + 220 + getPic_definite_lat(m_lat)) / (600 * 1.5);
        break;
    case 17:
        real_lat = (lat + 630 + getPic_definite_lat(m_lat)) / (1200 * 1.5);
        break;
    default:
        real_lat = (lat + 630 + getPic_definite_lat(m_lat)) / (1200 * 1.5);
        break;
    }
    return real_lat * (max_lat - min_lat) * (-1) + max_lat;
}
//转double解决精度的问题
double QStringparseDouble(const QString &str)
{
    double result = 0.0;
    bool isFractional = false;
    int startIndex = str.indexOf('.'); // 找到小数点的位置

    for (int i = 0; i < str.length(); ++i) {
        QChar ch = str.at(i);
        if (ch.isDigit()) {
            if (i < startIndex) {
                result = result * 10 + ch.digitValue();
            } else if (i > startIndex) {
                isFractional = true;
                result += ch.digitValue() * pow(10, -(i - startIndex));
            }
        }
    }
    if (isFractional) {
        return result;
    } else {
        return trunc(result); // 如果没有小数部分，返回整数部分
    }
}

//计算实际距离
double calculateDistance(double x_lon, double x_lat, double y_lon, double y_lat)
{
    // 地球半径，单位为千米
    const double EarthRadius = 6371.0;

    // 将经纬度转换为弧度
    double lat1 = x_lat * M_PI / 180.0;
    double lon1 = x_lon * M_PI / 180.0;
    double lat2 = y_lat * M_PI / 180.0;
    double lon2 = y_lon * M_PI / 180.0;
    // 计算经纬度差值
    double dLat = lat2 - lat1;
    double dLon = lon2 - lon1;
    // 哈弗西公式
    double a = std::sin(dLat / 2) * std::sin(dLat / 2)
               + std::cos(lat1) * std::cos(lat2) * std::sin(dLon / 2) * std::sin(dLon / 2);
    double c = 2 * std::atan2(std::sqrt(a), std::sqrt(1 - a));
    // 计算距离，将结果转换为米
    return EarthRadius * c * 1000.0;
}

//路网数据绘图
void Navigation::paintRoads()
{
    //太小就不画图了
    if (m_zoom < 14)
        return;
    //响应函数
    QPainter painter(ui->mapWidget_7);
    // 设置画笔样式
    QPen pen(Qt::blue);
    pen.setWidth(1);
    painter.setPen(pen);
    //绘制路网图
    for (int i = 0; i < roadlist.count(); i++) {
        for (int j = 0; j < roadlist.at(i).node_id.count() - 1; j++) {
            QString cur_node = roadlist.at(i).node_id.at(j);
            QString nxt_node = roadlist.at(i).node_id.at(j + 1);

            painter.drawLine(QLine(getPiclon(QStringparseDouble(nodeStrmap.value(cur_node).lon)),
                                   getPiclat(QStringparseDouble(nodeStrmap.value(cur_node).lat)),
                                   getPiclon(QStringparseDouble(nodeStrmap.value(nxt_node).lon)),
                                   getPiclat(QStringparseDouble(nodeStrmap.value(nxt_node).lat))));
        }
    }
    //绘制点
    painter.setPen(Qt::red);
    for (int i = 0; i < nodeIndexMap.count(); i++) {
        painter.drawEllipse(QPointF(getPiclon(QStringparseDouble(nodeIndexMap.value(i).lon)),
                                    getPiclat(QStringparseDouble(nodeIndexMap.value(i).lat))),0.5,0.5);
    }
    //qDebug() << "finished painting roads!";
    painter.setPen(QPen(Qt::black, 3));
    painter.setBrush(Qt::red);

    if (isSelecting == false)
        return;
    if (isCalculating == true) {
        if (isSelectingStartPoint == true || haveSelectedStartPoint == true) // 在选或者已选
        {
            haveSelectedStartPoint = true;
            double x = getPiclon(startpoint_lon), y = getPiclat(startpoint_lat);
            qDebug() << "painting startpoint" << x << y;
            painter.drawEllipse(QPointF(x, y), 5, 5);
        }
        if (isSelectingStartPoint == false || haveSelectedEndPoint == true) {
            haveSelectedEndPoint = true;
            double x = getPiclon(endpoint_lon), y = getPiclat(endpoint_lat);
            qDebug() << "painting endpoint" << x << y;
            painter.drawEllipse(QPointF(x, y), 5, 5);
        }
    } else {
        double sx = getPiclon(QStringparseDouble(nodeIndexMap.value(start_index).lon)),
               sy = getPiclat(QStringparseDouble(nodeIndexMap.value(start_index).lat));
        double ex = getPiclon(QStringparseDouble(nodeIndexMap.value(end_index).lon)),
               ey = getPiclat(QStringparseDouble(nodeIndexMap.value(end_index).lat));
        painter.drawEllipse(QPointF(sx, sy), 5, 5);
        painter.drawEllipse(QPointF(ex, ey), 5, 5);
    }

    //绘制最短路的路径
    if (min_dist_paths.empty())
        return;
    qDebug() << "painting shortestpath";
    painter.setPen(QPen(Qt::red, 3));
    painter.setBrush(Qt::NoBrush);
    for (int i = 0; i < min_dist_paths.count() - 1; i++) {
        int cur_node = min_dist_paths.at(i);
        int nxt_node = min_dist_paths.at(i + 1);
        painter.drawLine(QLine(getPiclon(QStringparseDouble(nodeIndexMap.value(cur_node).lon)),
                               getPiclat(QStringparseDouble(nodeIndexMap.value(cur_node).lat)),
                               getPiclon(QStringparseDouble(nodeIndexMap.value(nxt_node).lon)),
                               getPiclat(QStringparseDouble(nodeIndexMap.value(nxt_node).lat))));
    }

    //绘制实时移动轨迹
    if (isNavigating == false) return;
    timer = new QTimer(this);
    isPaused = false;
    qDebug() << "Ready to navigate!";
    painter.setPen(QPen(Qt::black, 3));
    painter.setBrush(Qt::yellow);
    qDebug() << "number of vetices on this road:" << min_dist_paths.count();
    qDebug() << "currentposition:" << currentPos;
    painter.drawEllipse(currentPos, 5, 5);

    //QMutexLocker locker(&mutex);
    //currentRoadIndex = 0;
    //currentPos = path_points[0];
    //step = 0.01;
    timer->start(16);
    disconnect(timer, &QTimer::timeout, this, &Navigation::updateAnimation);
    QObject::connect(timer, &QTimer::timeout, this, &Navigation::updateAnimation);
}

void Navigation::updateAnimation()
{
    //qDebug() << currentRoadIndex << "updaing...";
    qDebug() << "currentRoadIndex" << currentRoadIndex;
    if (isPaused == true)
        return;
    if (currentRoadIndex < path_points.size() - 1) {
        QPointF start = path_points[currentRoadIndex];
        QPointF end = path_points[currentRoadIndex + 1];

        currentPos = start * (1 - step) + end * step;

        // 更新轨迹点
        ui->mapWidget_7->update();

        double speed = 1 / calculateDistance(getReal_lon(start.x()),getReal_lat(start.y()),getReal_lon(end.x()),getReal_lat(end.y()));
        step += 1 * speed;
        qDebug() << "speed:" << speed << ", step:" << step;
        if (step >= 1.0) {
            step = 0.01;
            currentRoadIndex++;
            qDebug() << "did it ?" << currentRoadIndex;
        }
    } else {
        timer->stop();
        ui->curGoalLabel_7->setText("已到达目的地！");
        //step = 0.01;
        /*
        if (timer != nullptr) {
            timer->stop();
            disconnect(timer, &QTimer::timeout, this, &Navigation::updateAnimation);
            delete timer;
            timer = nullptr;
        }
        */
        return;
    }
}

//搜索
void Navigation::on_selectBtn_7_clicked(bool checked)
{
    isSearching = true;
}
void Navigation::on_stop_selecBtn_7_clicked(bool checked)
{
    isSelecting = false;
}
void Navigation::on_backBtn_7_clicked(bool checked)
{
    isSearching = false;
    m_lng = 116.178543;
    m_lat = 39.738114;
    m_zoom = 15;
    sendMapRequest();
}
//选点
void Navigation::on_startpointBtn_7_clicked(bool checked)
{
    if (isCalculating == false) {
        QMessageBox::information(this, tr("提示"), tr("正在行进中，无法修改起点！"));
        return;
    }
    isSelecting = true;
    isSelectingStartPoint = true;
}
void Navigation::on_endpointBtn_7_clicked(bool checked)
{
    if (isCalculating == false) {
        QMessageBox::information(this,tr("提示"),tr("正在行进中，请点击修改终点按钮进行目的地修改！"));
        return;
    }
    isSelecting = true;
    isSelectingStartPoint = false;
}
void Navigation::on_clearBtn_7_clicked(bool checked)
{
    isSelecting = false;
    isCalculating = true;
    isNavigating = false;
    isPaused = false;
    isSelectingStartPoint = false;
    startpoint_lat = endpoint_lat = 0.0;
    startpoint_lon = endpoint_lon = 0.0;
    //轨迹清零
    start_index = end_index = 0;
    currentRoadIndex = 0;
    haveSelectedStartPoint = haveSelectedEndPoint = false;
    min_dist = 0x3f3f3f3f;
    min_dist_paths.clear();
    //文字显示
    ui->curGoalLabel_7->setText("正在设置目的地...");
    ui->straightDisLabel_7->setText("直线距离为：");
    ui->minDisLabel_7->setText("最短距离为：");
    sendMapRequest();
}
//计算距离

void Navigation::getMinDistance()
{
    QString startpoint = QString::number(startpoint_lat, 'f', 7) + ","
                         + QString::number(startpoint_lon, 'f', 7);
    QString endpoint = QString::number(endpoint_lat, 'f', 7) + ","
                       + QString::number(endpoint_lon, 'f', 7);
    qDebug() << "startpoint:" << startpoint << "endpoint:" << endpoint;
    QPair<int, int> nearpoint = findNearPoint(startpoint_lon,startpoint_lat,endpoint_lon,endpoint_lat);
    start_index = nearpoint.first, end_index = nearpoint.second;
    qDebug() << "start_index:" << start_index << ":" << nodeIndexMap.value(start_index).lon << ","
             << nodeIndexMap.value(start_index).lat;
    qDebug() << "end_index:" << end_index << ":" << nodeIndexMap.value(end_index).lon << ","
             << nodeIndexMap.value(end_index).lat;
    getMinPath(start_index, end_index, startpoint_lon, startpoint_lat, endpoint_lon, endpoint_lat);
}
//将路网数据建图
void Navigation::getMinPath(
    int start_index, int end_index, double s_lon, double s_lat, double e_lon, double e_lat)
{
    qDebug() << "number of vetex:" << nodeIndexMap.count();
    GeoGraph g(nodeIndexMap.count());
    for (int i = 0; i < roadlist.count(); i++) {
        for (int j = 0; j < roadlist.at(i).node_id.count() - 1; j++) {
            QString cur_node = roadlist.at(i).node_id.at(j);
            QString nxt_node = roadlist.at(i).node_id.at(j + 1);
            //QString::number(nodeStrmap.value(cur_node).lon,'f',7)
            //记录是否在路上
            double cur_lon = QStringparseDouble(nodeStrmap.value(cur_node).lon);
            double cur_lat = QStringparseDouble(nodeStrmap.value(cur_node).lat);
            double nxt_lon = QStringparseDouble(nodeStrmap.value(nxt_node).lon);
            double nxt_lat = QStringparseDouble(nodeStrmap.value(nxt_node).lat);
            double dist = calculateDistance(cur_lon, cur_lat, nxt_lon, nxt_lat);
            //双向边
            g.addEdge(nodeStrmap.value(cur_node).index, nodeStrmap.value(nxt_node).index, dist);
            g.addEdge(nodeStrmap.value(nxt_node).index, nodeStrmap.value(cur_node).index, dist);
            //qDebug() << "road:" << nodeStrmap.value(cur_node).index << nodeStrmap.value(nxt_node).index << dist;
        }
    }
    Dijkstra cur_dij(g);
    min_dist_paths = cur_dij.findShortestPathBetween(start_index, end_index);
    min_dist = cur_dij.shortestPathLength(start_index, end_index);

    path_points.clear();
    for (int i = 0; i < min_dist_paths.count(); i++) {
        int cur_node = min_dist_paths.at(i);
        path_points.append(QPointF(getPiclon(QStringparseDouble(nodeIndexMap.value(cur_node).lon)),
                                   getPiclat(QStringparseDouble(nodeIndexMap.value(cur_node).lat))));
    }
}

QPair<int, int> Navigation::findNearPoint(double s_lon, double s_lat, double e_lon, double e_lat)
{
    QVector<bool> IsOnRoad(nodeIndexMap.count(), false);
    for (int i = 0; i < roadlist.count(); i++) {
        for (int j = 0; j < roadlist.at(i).node_id.count() - 1; j++) {
            QString cur_node = roadlist.at(i).node_id.at(j);
            QString nxt_node = roadlist.at(i).node_id.at(j + 1);
            //记录是否在路上
            IsOnRoad[nodeStrmap.value(cur_node).index] = true;
            IsOnRoad[nodeStrmap.value(nxt_node).index] = true;
        }
    }

    double min_dis = 0x3f3f3f3f;
    int min_s_index = -1;
    double ori_dist = calculateDistance(s_lon, s_lat, e_lon, e_lat);
    for (int i = 0; i < nodeIndexMap.count(); i++) {
        if (IsOnRoad[i] == false)
            continue;
        double cur_dist = calculateDistance(s_lon,s_lat,
                                            QStringparseDouble(nodeIndexMap.value(i).lon),
                                            QStringparseDouble(nodeIndexMap.value(i).lat));
        double st_dist = calculateDistance(e_lon,e_lat,
                                           QStringparseDouble(nodeIndexMap.value(i).lon),
                                           QStringparseDouble(nodeIndexMap.value(i).lat));
        if (st_dist < ori_dist)
            continue;
        //qDebug() << cur_dist;
        if (cur_dist < min_dis) {
            min_dis = cur_dist;
            min_s_index = i;
        }
    }
    min_dis = 0x3f3f3f3f;
    int min_e_index = -1;
    ori_dist = calculateDistance(s_lon, s_lat, e_lon, e_lat);
    for (int i = 0; i < nodeIndexMap.count(); i++) {
        if (IsOnRoad[i] == false)
            continue;
        double cur_dist = calculateDistance(e_lon,e_lat,
                                            QStringparseDouble(nodeIndexMap.value(i).lon),
                                            QStringparseDouble(nodeIndexMap.value(i).lat));
        double st_dist = calculateDistance(s_lon,s_lat,
                                           QStringparseDouble(nodeIndexMap.value(i).lon),
                                           QStringparseDouble(nodeIndexMap.value(i).lat));
        if (st_dist < ori_dist)
            continue;
        //qDebug() << cur_dist;
        if (cur_dist < min_dis) {
            min_dis = cur_dist;
            min_e_index = i;
        }
    }
    qDebug() << "min_index:" << min_s_index << min_e_index;
    if (min_s_index == -1 || min_e_index == -1) {
        qDebug() << "Error! Incorrect dot!";
        return qMakePair(0, 0);
    } else
        return qMakePair(min_s_index, min_e_index);
}

double Navigation::getRealDistance()
{
    double path_length = 0;
    for (int i = 0; i < min_dist_paths.count() - 1; i++) {
        int cur_index = min_dist_paths.at(i);
        int nxt_index = min_dist_paths.at(i + 1);
        path_length += calculateDistance(QStringparseDouble(nodeIndexMap.value(cur_index).lon),
                                         QStringparseDouble(nodeIndexMap.value(cur_index).lat),
                                         QStringparseDouble(nodeIndexMap.value(nxt_index).lon),
                                         QStringparseDouble(nodeIndexMap.value(nxt_index).lat));
    }
    return path_length;
}

void Navigation::on_finishBtn_7_clicked(bool checked)
{
    isSelecting = false;
    isCalculating = true;
    isNavigating = false;
    isPaused = false;
    isSelectingStartPoint = false;
    startpoint_lat = endpoint_lat = 0.0;
    startpoint_lon = endpoint_lon = 0.0;
    haveSelectedStartPoint = haveSelectedEndPoint = false;
    //轨迹相关指针清零
    start_index = end_index = 0;
    currentRoadIndex = 0;
    min_dist = 0x3f3f3f3f;
    min_dist_paths.clear();
    //设置文字显示
    ui->straightDisLabel_7->setText("直线距离为：");
    ui->minDisLabel_7->setText("最短距离为：");
    ui->curGoalLabel_7->setText("准备开始导航...");
    //sendMapRequest();
}

void Navigation::on_navigateBtn_7_clicked(bool checked)
{
    isCalculating = false;
    isNavigating = true;
    isPaused = false;
    if (startpoint_lon < 1e-6 || startpoint_lat < 1e-6 || endpoint_lon < 1e-6 || endpoint_lat < 1e-6)
        return;
    double cur_distance = calculateDistance(startpoint_lon,
                                            startpoint_lat,
                                            endpoint_lon,
                                            endpoint_lat);
    qDebug() << "distance:" << cur_distance << Qt::endl;
    ui->curGoalLabel_7->setText("正在前往目的地...");
    ui->straightDisLabel_7->setText("直线距离为：" + QString::number(cur_distance, 'f', 3));
    getMinDistance();
    if (min_dist_paths.empty()) {
        ui->minDisLabel_7->setText("您选择的两点在本图中不连通！");
        ui->curGoalLabel_7->setText("无法前往目的地！");
        isCalculating = true;
        isNavigating = false;
    } else
        ui->minDisLabel_7->setText("最短距离为：" + QString::number(getRealDistance(), 'f', 3));
    currentRoadIndex = 0;
    step = 0.01;
    sendMapRequest();
}

void Navigation::on_alterpointBtn_7_clicked(bool checked)
{
    isPaused = true;
    /*
    start_index = min_dist_paths.at(currentRoadIndex);
    startpoint_lon = QStringparseDouble(nodeIndexMap.value(start_index).lon);
    startpoint_lat = QStringparseDouble(nodeIndexMap.value(start_index).lat);
    min_dist_paths.clear();
    */
}

void Navigation::on_continueBtn_7_clicked(bool checked)
{
    isPaused = false;
    //on_navigateBtn_clicked(true);
}

